"""多层感知机训练"""
from tensorflow.examples.tutorials.mnist import input_data
from keras.models import  Sequential
from keras.layers import Dense

#模拟原始灰度数据读入
img_size=28
num=10
mnist=input_data.read_data_sets("./data",one_hot=True)
X_train,y_train,X_test,y_test=mnist.train.images,mnist.train.labels,mnist.test.images,mnist.test.labels
X_train=X_train.reshape(-1,img_size,img_size)
X_test=X_test.reshape(-1,img_size,img_size)
X_train=X_train*255
X_test=X_test*255
y_train=y_train.reshape(-1,num)
y_test=y_test.reshape(-1,num)
print(X_train.shape)
print(y_train.shape)

#全连接层只能输入一维
num_pixels = X_train.shape[1] * X_train.shape[2]
X_train = X_train.reshape(X_train.shape[0],num_pixels).astype('float32')
X_test = X_test.reshape(X_test.shape[0],num_pixels).astype('float32')

#归一化
X_train=X_train/255
X_test=X_test/255

# one hot编码,这里编好了，省略
#y_train = np_utils.to_categorical(y_train)
#y_test = np_utils.to_categorical(y_test)

#搭建网络
def baseline():
    """
    optimizer：优化器，如Adam
    loss：计算损失，当使用categorical_crossentropy损失函数时，标签应为多类模式，例如如果你有10个类别，
    每一个样本的标签应该是一个10维的向量，该向量在对应有值的索引位置为1其余为0
    metrics: 列表，包含评估模型在训练和测试时的性能的指标
    """
    model=Sequential()
    #第一步是确定输入层的数目：在创建模型时用input_dim参数确定,例如，有784个个输入变量，就设成num_pixels。
    #全连接层用Dense类定义：第一个参数是本层神经元个数，然后是初始化方式和激活函数,初始化方法有0到0.05的连续型均匀分布（uniform
    #Keras的默认方法也是这个，也可以用高斯分布进行初始化normal，初始化实际就是该层连接上权重与偏置的初始化
    model.add(Dense(num_pixels,input_dim=num_pixels,kernel_initializer='normal',activation='relu'))
    #softmax是一种用到该层所有神经元的激活函数
    model.add(Dense(num,kernel_initializer='normal',activation='softmax'))
    #categorical_crossentropy适用于多分类问题，并使用softmax作为输出层的激活函数的情况
    model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
    return model

#训练模型
model = baseline()
"""
batch_size
整数
每次梯度更新的样本数。
未指定，默认为32
epochs
整数
训练模型迭代次数
verbose
日志展示，整数
0:为不在标准输出流输出日志信息
1:显示进度条
2:每个epoch输出一行记录
对于一个有 2000 个训练样本的数据集,将 2000 个样本分成大小为 500 的 batch，那么完成一个 epoch 需要 4 个 iteration
"""
model.fit(X_train,y_train,validation_data=(X_test,y_test),epochs=10,batch_size=200,verbose=2)
#模型概括打印
model.summary()
#model.evaluate（）返回的是 损失值和你选定的指标值（例如，精度accuracy）
"""
verbose：控制日志显示的方式
verbose = 0  不在标准输出流输出日志信息
verbose = 1  输出进度条记录
"""
scores = model.evaluate(X_test,y_test,verbose=0)
print(scores)

#模型保存
model_dir="./Dense.h5"
model.save(model_dir)